#!/usr/bin/env python3

# Copyright (c) 2020-2021 Fpemud <fpemud@sina.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.


from ..._util import Util, WinRegistry
from ..._prototype import CustomAction


class SetResolution(CustomAction):

    def __init__(self, width, height):
        assert 0 < width <= 0xFFFF and 0 < height <= 0xFFFF
        self._width = width
        self._height = height

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            rootKey = reg.get_local_machine_current_control_set_key() + "\\Hardware Profiles\\0001\\System\\CurrentControlSet\\Control\\VIDEO"
            subkeys = reg.get_subkeys(rootKey)
            assert len(subkeys) == 1
            reg.add_or_modify(rootKey + "\\" + subkeys[0] + "\\0000", "DefaultSettings.XResolution", "REG_DWORD", self._width)
            reg.add_or_modify(rootKey + "\\" + subkeys[0] + "\\0000", "DefaultSettings.YResolution", "REG_DWORD", self._height)

    def get_after(self):
        return []

    def get_before(self):
        return []


class SetBackgroundColor(CustomAction):

    DEFAULT_BACKGROUND_COLOR = 0x000000             # FIXME

    def __init__(self, color, for_user=None):
        self._color = color
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                reg.modify("HKU\\%s\\Control Panel\\Colors" % (u), "Background", "REG_SZ", self._convertColorNumber(self._color))

    def get_after(self):
        return []

    def get_before(self):
        return []

    @staticmethod
    def _convertColorNumber(color_hex):
        assert 0x000000 <= color_hex <= 0xFFFFFF
        r = (color_hex >> 16) & 0xFF
        g = (color_hex >> 8) & 0xFF
        b = color_hex & 0xFF
        return f"{r} {g} {b}"


class DisableWallpaper(CustomAction):

    # this registry entry also applies to Server 2003, Vista and Windows 7

    def __init__(self, for_user=None):
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "Wallpaper", "REG_SZ", "")

    def get_after(self):
        return []

    def get_before(self):
        return []


class UseStockWallpaper(CustomAction):

    def __init__(self, wallpaper_name, for_user=None):
        if wallpaper_name == "Ascent":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Autumn":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Azul":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Bliss":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.bmp"
            self._position = "stretch"
        elif wallpaper_name == "Blue Lace 16":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Coffee Bean":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Crystal":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "FeatherTexture":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Follow":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Friend":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Gone Fishing":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Greenstone":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Home":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Moon flower":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Peace":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Power":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Prairie Wind":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Purple flower":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Radiance":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Red moon desert":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Rhododendron":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Ripple":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "River Sumida":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Santa Fe Stucco":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Soap Bubbles":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        elif wallpaper_name == "Stonehenge":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Tulips":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Vortec space":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Wind":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Windows XP":
            self._path = f"%SystemRoot%\\Web\\Wallpaper\\{wallpaper_name}.jpg"
            self._position = "stretch"
        elif wallpaper_name == "Zapotec":
            self._path = f"%SystemRoot%\\{wallpaper_name}.bmp"
            self._position = "tile"
        else:
            assert False
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "Wallpaper", "REG_SZ", self._path)
                if self._position == "center":
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "WallpaperStyle", "REG_SZ", "0")
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "TileWallpaper", "REG_SZ", "0")
                elif self._position == "tile":
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "WallpaperStyle", "REG_SZ", "1")
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "TileWallpaper", "REG_SZ", "1")
                elif self._position == "stretch":
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "WallpaperStyle", "REG_SZ", "2")
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "TileWallpaper", "REG_SZ", "0")
                else:
                    assert False

    def get_after(self):
        return []

    def get_before(self):
        return []


class UseCustomWallpaper(CustomAction):

    def __init__(self, filepath, position, for_user=None):
        assert len(filepath) > 0
        assert position in ["center", "tile", "stretch"]

        self._path = filepath
        self._position = position
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "Wallpaper", "REG_SZ", self._path)
                if self._position == "center":
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "WallpaperStyle", "REG_SZ", "0")
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "TileWallpaper", "REG_SZ", "0")
                elif self._position == "tile":
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "WallpaperStyle", "REG_SZ", "1")
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "TileWallpaper", "REG_SZ", "1")
                elif self._position == "stretch":
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "WallpaperStyle", "REG_SZ", "2")
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "TileWallpaper", "REG_SZ", "0")
                else:
                    assert False

    def get_after(self):
        return []

    def get_before(self):
        return []


class DisableScreenSaver(CustomAction):

    # this registry entry also applies to Server 2003, Vista and Windows 7

    def __init__(self, for_user=None):
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                assert reg.get_value("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaveActive", "REG_SZ") == "1"
                reg.delete("HKU\\%s\\Control Panel\\Desktop" % (u), "SCRNSAVE.EXE")

    def get_after(self):
        return []

    def get_before(self):
        return []


class UseStockScreenSaver(CustomAction):

    def __init__(self, screen_saver_name, timeout, password, for_user=None):
        if screen_saver_name == "3D FlowerBox":
            self._path = "%SystemRoot%\\system32\\ssflwbox.scr"
        elif screen_saver_name == "3D Flying Objects":
            self._path = "%SystemRoot%\\system32\\ss3dfo.scr"
            # FIXME: Control Panel/Screen Saver.3DFlyingObj/*
        elif screen_saver_name == "3D Pipes":
            self._path = "%SystemRoot%\\system32\\sspipes.scr"
            # FIXME: Control Panel/Screen Saver.3DPipes/*
        elif screen_saver_name == "3D Text":
            self._path = "%SystemRoot%\\system32\\sstext3d.scr"
        elif screen_saver_name == "Beziers":
            self._path = "%SystemRoot%\\system32\\ssbezier.scr"
            # FIXME: Control Panel/Screen Saver.Bezier/*
        elif screen_saver_name == "Blank":
            self._path = "%SystemRoot%\\system32\\scrnsave.scr"
        elif screen_saver_name == "Marquee":
            self._path = "%SystemRoot%\\system32\\ssmarque.scr"
            # FIXME: Control Panel/Screen Saver.Marquee/*
        elif screen_saver_name == "My Pictures Slideshow":
            self._path = "%SystemRoot%\\system32\\ssmypics.scr"
        elif screen_saver_name == "Mystify":
            self._path = "%SystemRoot%\\system32\\ssmyst.scr"
            # FIXME: Control Panel/Screen Saver.Mystify/*
        elif screen_saver_name == "Starfield":
            self._path = "%SystemRoot%\\system32\\ssstars.scr"
            # FIXME: Control Panel/Screen Saver.Stars/*
        elif screen_saver_name == "Windows XP":
            self._path = "%SystemRoot%\\system32\\logon.scr"
        else:
            assert False
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                assert reg.get_value("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaveActive", "REG_SZ") == "1"
                reg.add_or_modify("HKU\\%s\\Control Panel\\Desktop" % (u), "SCRNSAVE.EXE", "REG_SZ", self._path)
                # if True:
                #     reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaveTimeOut", "REG_SZ", "300")
                # if True:
                #     reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaverIsSecure", "REG_SZ", "1")

    def get_after(self):
        return []

    def get_before(self):
        return []


class UseCustomScreenSaver(CustomAction):

    def get_after(self):
        return []

    def get_before(self):
        return []


class InstallAndUseCustomScreenSaver(CustomAction):

    def __init__(self, screen_saver_file, timeout, password, for_user=None):
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                assert reg.get_value("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaveActive", "REG_SZ") == "1"
                reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "SCRNSAVE.EXE", "REG_SZ", None)
                if True:
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaveTimeOut", "REG_SZ", "300")
                if True:
                    reg.modify("HKU\\%s\\Control Panel\\Desktop" % (u), "ScreenSaverIsSecure", "REG_SZ", "1")

    def get_after(self):
        return []

    def get_before(self):
        return []


class DisableAutoRun(CustomAction):

    # this registry entry also applies to Server 2003, Vista

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                reg.modify("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer" % (u), "NoDriveTypeAutoRun", "REG_DWORD", 177)

    def get_after(self):
        return []

    def get_before(self):
        return []


class SetLanguageBarShowStatus(CustomAction):

    def __init__(self, show_status, for_user=None):
        if show_status == "floating":
            # floating on desktop
            self._status = 0
        elif show_status == "hidden":
            self._status = 3
        elif show_status == "docked":
            # docked in task bar
            self._status = 4
        else:
            assert False
        self._user = for_user

    def run(self, action_name, s, ts, work_dir):
        with work_dir.mount_image_file() as mp:
            reg = WinRegistry(mp.drive_c_dir)
            for u in Util.getListByItem(reg.get_users(), self._user):
                reg.modify("HKU\\%s\\SOFTWARE\\Microsoft\\CTF\\LangBar" % (u), "ShowStatus", "REG_DWORD", self._status)

    def get_after(self):
        return []

    def get_before(self):
        return []
